/* eslint-disable no-trailing-spaces */
import tool from './tools'
// 公共属性
const unitWidth = 100 // 小格子宽
const unitHeight = 30 // 小格子高
const unitSpace = 50 // 每个小格子之间的左右距离
const unitTopSpace = 20 // 每个小格子之间的上下距离
const unitFirstPosition = { 'left': 190, 'top': 70 } // 整个大模块第一个坐标位置
const sonFillWidth = 225 // 每个子模块宽度求和后再 补偿 宽度距离
const sonFillHeight = 200 // 每个条件之间的补偿
const isScan = { 'YN': -125, 'YYAndNN': -5, 'NY': 115 } // 前后是否有扫码  补偿机制(YN: 前有扫码 后无扫码 ,YYAndNN 前有后有，前无后无 ;NY 前无后有 )
const selectTwo = 120 // 选择条件大于1时 影响子坐标位置 误差补偿
const selectPositionFirst = { 'y': 345, 'n': 225 } // 选择条件的第一个元素坐标位置 有扫码补偿 345，无扫码补偿225

// 应用策略模式 将策略项取出来
let WeightNum = {
  IsStep: (value) => value === 0,
  IsSelect: (value) => value === 4.1
}

/**
 * 处理拖拽数据的类
 * @class
 */
class StandardData {
  // eslint-disable-next-line space-before-function-paren
  constructor() {
    this._data = [
      {
        'text': '步骤',
        'icon': 'edifBuzhou.png',
        'eng': 'step',
        'weight': 0,
        'flagCheck': 'checkedStep'
      },
      {
        'text': '扫码',
        'eng': 'scan',
        'weight': 1.1,
        'flagCheck': 'checkedScan'
      },
      {
        'text': '图片',
        'icon': 'editImage.png',
        'eng': 'picture',
        'weight': 2.2,
        'flagCheck': 'checkedTopNum'
      },
      {
        'text': 'PDF',
        'icon': 'editPDF.png',
        'eng': 'pdf',
        'weight': 2.2,
        'flagCheck': 'checkedTopNum'
      },

      {
        'text': '视频',
        'icon': 'editvid.png',
        'eng': 'video',
        'weight': 2.2,
        'flagCheck': 'checkedTopNum'
      },
      {
        'text': 'PDF',
        'icon': 'editPDF.png',
        'eng': 'pdf',
        'weight': 2.2,
        'flagCheck': 'checkedTopNum'
      },
      // {
      //   'text': '模型',
      //   'icon': 'editMoxing.png',
      //   'eng': 'textInput',
      //   'weight': 3.1,
      //   'flagCheck': 'checkedTextInput'
      // },
      {
        'text': '视频记录',
        'eng': 'video_record',
        'weight': 3.2,
        'flagCheck': 'checkedBottomNum'
      },
      {
        'text': '拍照记录',
        'eng': 'photo_record',
        'weight': 3.2,
        'flagCheck': 'checkedBottomNum'
      },
      {
        'text': '状态输入',
        'eng': 'stateInput',
        'weight': 3.3,
        'flagCheck': 'checkedStateInput'
      },
      {
        'text': '状态选择',
        'eng': 'stateSelect',
        'weight': 3.4,
        'flagCheck': 'checkedStateSelect'
      },
      {
        'text': '呼叫',
        'eng': 'call',
        'weight': 4.2,
        'flagCheck': 'checkedCall'
      },
      // {
      //   'text': '完成',
      //   'eng': 'finish',
      //   'weight': 100,
      //   'flagCheck': 'checkedFinish'
      // },
      {
        'text': '选择',
        'eng': 'select',
        'weight': 4.1,
        'flagCheck': 'checkedSelect'
      }
    ]
  }

  /**
   * 得到一个 _data数组的对象策略 替代下面可能出现的4.1 1.0 select等 
   * obj.step 就一定是step的内容值  不需要传递 ‘step’ 才能获取，方便以后 不是'step'了
   */
  getStrategyData () {
    let result = {}
    this._data.forEach(item => {
      let key = item.eng
      result[key] = item
    })
    return result
  }

  /**
   * 对外暴露选择参数
   * @returns
   */
  getSelectData () {
    return this._data
  }

  /**
   * 根据中文 得到英文名称
   * @param {string} chi 
   */
  getEngByChinese (chi) {
    return this._data.filter(item => item.text === chi)[0].eng
  }

  /**
   * 根据权值 得到英文
   * @param {number} wei 
   */
  getEngByWeight (wei) {
    return this._data.filter(item => item.weight === wei)[0].eng
  }

  /**
   * 根据权值 获得点击标记
   * @param {number} wei 
   */
  getClickFlag (wei) {
    return this._data.filter(item => item.weight === wei)[0].flagCheck
  }

  /**
   *每次模块变更都会走这个方法 重新计算坐标位置和宽度，子模块元素，每条线路自动添加完成
   * @param {array} arr 
   */
  formatting (arr) {
    let OneItemData = this.getStrategyData()
    if (arr.length > 0) {
      // 先计算出第一个的宽度和高度，保留第一个的坐标值
      let firstPosition = arr[0].unitBasicStep
      arr[0].unitStep = 1 // 给第一个赋步骤
      conditionCount(arr)
      dealFinish(arr)
      widthAndHeight(arr)
      position(arr, firstPosition.left, firstPosition.top, arr[0].unitWidth)
    }

    /**
     * 实时处理自动添加完成
     * @param {*} arr 
     */
    function dealFinish (arr) {
      let finishObj = OneItemData.finish
      main(arr)
      /**
       * 先删除所有步骤中的完成,在循环结束后 往最后一个模块添加完成
       * @param {*} arr 
       */
      function main (arr) {
        for (let i = 0; i < arr.length; i++) {
          if (arr[i].conditionNum > 0) {
            son(arr[i].selectObject, arr[i].conditionNum)
          }
          if (arrIsHasValue(arr[i].unitElement, 'weight', finishObj.weight)) { // 有完成，需要删除
            arr[i].unitElement = getArrNoHasValue(arr[i].unitElement, 'weight', finishObj.weight)
            arr[i].contentNature = getArrNoHasValue(arr[i].contentNature, 'name', finishObj.eng)
          }
        }
        // 开始往模块最后添加完成
        arr[arr.length - 1].unitElement.push({ text: finishObj.text, weight: finishObj.weight }) // 插入标准位
        arr[arr.length - 1].contentNature.push(getNatureData(finishObj.eng))
      }

      function son (obj, num) {
        for (let i = 0; i < num; i++) {
          let tt = getSonBranchKey(i + 1)
          main(obj[tt])
        }
      }
    }

    /**
     * 计算conditionNum 选择模块 下的子模块个数
     * @param {array} arr 
     */
    function conditionCount (arr) {
      main(arr)

      function main (arr) {
        for (let i = 0; i < arr.length; i++) {
          let myObj = arr[i].selectObject
          let myNature = arr[i].contentNature
          let conNum = Object.keys(myObj).length
          arr[i].conditionNum = conNum < 0 ? 0 : conNum // 设置选择的分支个数
          // 有删除时
          let conditionDelete = getDeleteKey(conNum, myObj)
          if (conditionDelete.length) {
            for (let j = 0; j < conditionDelete.length; j++) {
              delete myObj[conditionDelete[j]]
              arr[i].conditionNum--
              if (arr[i].conditionNum === 0) {
                arr[i].selectObject = {}
                arr[i].unitElement = arr[i].unitElement.filter(item => item.weight !== OneItemData.select.weight)
              }
              arr[i].contentNature = dealBranchData(myNature, conditionDelete[j], arr[i].conditionNum)
            }
          }
          // 删除后 处理selectObject的字段 （condition_2 被删除了 condition_3 变成condition_2 也就是 排序一样 1 2 3 =》2没了 3变2）
          if (conNum !== arr[i].conditionNum) {
            arr[i].selectObject = replaceKey(Object.keys(myObj), myObj)
          }
          // 接着在处理子条件
          if (arr[i].conditionNum > 0) {
            son(arr[i].selectObject, arr[i].conditionNum)
          }
        }

        /**
         * 检测并收集需要删除的key值
         * 因为被删除的 key 所对应的value是空值 
         * @param {number} num 子模块数据
         * @param {object} objs 选择对象 子模块所在的对象
         * @returns array 需要删除的key值
         */
        function getDeleteKey (num, objs) {
          let result = []
          for (let i = 0; i < num; i++) {
            let tt = getSonBranchKey(i + 1)
            if (objs[tt].length === 0) {
              result.push(tt)
            }
          }
          return result
        }

        /**
         * 重新赋值key值
         * @param {array} arr 子模块中的 key值数组
         * @param {object} objs 子模块所在的对象
         * @returns object
         */
        function replaceKey (arr, objs) {
          let result = {}
          for (let z = 0; z < arr.length; z++) {
            let kk = getSonBranchKey(z + 1)
            let myKey = arr[z]
            result[kk] = objs[myKey]
          }
          return result
        }
      }

      /**
       * 删除选择的 分支 数据模块
       * @param {Array} nature contentNature 数组(全部的详情模块)
       * @param {String} names 被删除分支名字
       * @param {Number} branchNum 分支剩余数
       */
      function dealBranchData (nature, names, branchNum) {
        console.log(names, branchNum)
        let result = nature.filter(item => item.name !== OneItemData.select.eng)

        if (branchNum > 0) {
          let seleteObjs = nature.filter(item => item.name === OneItemData.select.eng)[0]
          let describeObj = seleteObjs.describeObj
          describeObj.titleArr = describeObj.titleArr.filter(item => item.branch !== names)
          describeObj.titleArr = dealBrachNames(describeObj.titleArr, branchNum)
          seleteObjs.describeObj = describeObj
          result.push(seleteObjs)
        }
        return result

        /**
         * 变更 branch数字段 修正分支名字 2分支删除了 3分支变成二分支
         * @param {Array} titleArr 
         * @param {Number} nums  分支数
         */
        function dealBrachNames (titleArr, nums) {
          for (let i = 0; i < nums; i++) {
            titleArr[i].branch = getSonBranchKey(i + 1)
          }
          return titleArr
        }
      }

      function son (obj, num) {
        for (let i = 0; i < num; i++) {
          let tt = getSonBranchKey(i + 1)
          main(obj[tt])
        }
      }
    }

    /**
     * 宽度高度计算
     * @param {array} arr 
     */
    function widthAndHeight (arr) {
      main(arr)

      function main (arr) {
        for (let i = 0; i < arr.length; i++) {
          if (arr[i].conditionNum > 0) {
            son(arr[i].selectObject, arr[i].conditionNum)
            let newSinWH = getSinWH(arr[i], arr[i].selectObject, arr[i].conditionNum)
            arr[i].unitWidth = newSinWH.width
            arr[i].unitHeight = newSinWH.height
          } else {
            let wh = getWidthAndHeight(arr[i].unitElement)
            arr[i].unitWidth = wh.width
            arr[i].unitHeight = wh.height
          }
        }
      }

      function son (obj, num) {
        for (let i = 0; i < num; i++) {
          let tt = getSonBranchKey(i + 1)
          main(obj[tt])
        }
      }

      /**
       * 返回每个模块的区间宽度和高度
       * @param {Array} arr 
       */
      function getWidthAndHeight (arr) {
        let result = { width: unitWidth, height: unitHeight }
        let widthArrayLength = arr.filter(item => item.weight < 1.2 || item.weight > 4).length
        result.width += (widthArrayLength * unitWidth + (widthArrayLength + 2) * unitSpace)
        let heightArrayLength = arr.filter(item => item.weight > 2 && item.weight < 4).length
        result.height += (heightArrayLength * unitHeight + heightArrayLength * unitTopSpace)
        return result
      }

      /**
       * 返回 子元素的宽度和高度
       * @param {object} mainObj 
       * @param {object} sinObj 
       * @param {number} num 
       */
      function getSinWH (mainObj, sinObj, num) {
        let result = { width: 0, height: 0 }
        let tt = getWidthAndHeight(mainObj.unitElement)
        result.width = tt.width
        for (let i = 0; i < num; i++) {
          let tt = getSonBranchKey(i + 1)
          let newWidth = sumWidthAndHeight(sinObj[tt])
          result.width = newWidth.width > result.width ? newWidth.width : result.width
          result.height += (newWidth.height + sonFillHeight)
        }
        // 到这一步已经计算出来了子元素的宽度和高度了
        result.width += sonFillWidth
        return result

        /**
         *  计算每个子元素的宽度和高度 
         * @param {Array} arr
         */
        function sumWidthAndHeight (arr) {
          let result = { width: 0, height: 0 }
          for (let i = 0; i < arr.length; i++) {
            result.width += arr[i].unitWidth
            result.height = arr[i].unitHeight > result.height ? arr[i].unitHeight : result.height
          }
          return result
        }
      }
    }

    /**
     * 坐标位置计算
     * @param {array} arr 操作数组
     * @param {number} leftNum 步骤所在的 x轴值
     * @param {number} topNum  步骤所在的 y轴值
     * @param {number} oldWidth 上一个模块所在的宽度
     */
    function position (arr, leftNum, topNum, oldWidth) {
      mainPosition(arr, leftNum, topNum, oldWidth)

      function mainPosition (arr, leftNum, topNum, oldWidth) {
        // 判断第一个是否有子条件
        if (arr[0].conditionNum > 0) {
          sonPosition(arr[0].selectObject, arr[0].conditionNum, arr[0].unitBasicStep.left, arr[0].unitBasicStep.top, arr[0].unitHeight)
        }
        for (let i = 1; i < arr.length; i++) {
          arr[i].unitBasicStep.left = stepLeft(arr[i - 1].unitElement, arr[i].unitElement, leftNum, oldWidth)
          arr[i].unitBasicStep.top = topNum
          leftNum = arr[i].unitBasicStep.left
          oldWidth = arr[i].unitWidth
          arr[i].unitStep = (i + 1)
          if (arr[i].conditionNum > 0) { // 有子元素
            sonPosition(arr[i].selectObject, arr[i].conditionNum, arr[i].unitBasicStep.left, arr[i].unitBasicStep.top, arr[i].unitHeight)
          }
        }

        /**
         * 计算左值坐标位置
         * @param {array} beforeArr 上一个步骤所包含的元素内容
         * @param {array} afterArr 这个步骤 所包含的元素内容
         * @param {number} leftNum 步骤的X坐标
         * @param {number} oldWidth 整个步骤模块所占的宽度
         */
        function stepLeft (beforeArr, afterArr, leftNum, oldWidth) {
          let result = 0
          if (isHaveScan(beforeArr) && !isHaveScan(afterArr)) { // 前有扫码 后无扫码
            result = leftNum + oldWidth + isScan.YN
          } else if ((isHaveScan(beforeArr) && isHaveScan(afterArr)) || (!isHaveScan(beforeArr) && !isHaveScan(afterArr))) { // 前有扫码 后有扫码 或 前无后无
            result = leftNum + oldWidth + isScan.YYAndNN
          } else if (!isHaveScan(beforeArr) && isHaveScan(afterArr)) { // 前无扫码 后有扫码
            result = leftNum + oldWidth + isScan.NY
          }
          return result
        }
      }

      /**
       * 重新计算出子元素的 leftNum,topNum,oldWidth值
       * @param {object} obj 子模块所在的区间
       * @param {number} num 选择下分支数量
       * @param {number} parentLeft 父轴步骤 x坐标
       * @param {number} parentTop 父轴步骤 Y坐标
       * @param {number} parentHeight 父轴 模块的高度
       */
      function sonPosition (obj, num, parentLeft, parentTop, parentHeight) {
        for (let i = 0; i < num; i++) {
          let tt = getSonBranchKey(i + 1)
          let leftNum = obj[tt][0].unitBasicStep.left = parentLeft + (isHaveScan(obj[tt][0].unitElement) ? selectPositionFirst.y : selectPositionFirst.n)
          let topNum = obj[tt][0].unitBasicStep.top = parentTop + (parentHeight * (i / num)) + selectTwo
          let oldWidth = obj[tt][0].unitWidth
          obj[tt][0].unitStep = 1
          mainPosition(obj[tt], leftNum, topNum, oldWidth)
        }
      }

      // 
      /**
       * 目标元素中是否有扫码元素
       * @param {array} arr 步骤所包含的 元素
       * @returns boolean
       */
      function isHaveScan (arr) {
        return arr.filter(item => item.weight === OneItemData.scan.weight).length > 0
      }
    }
  }

  /**
   * 这是将嵌套数组 拉平成一维数组
   * @param {array} arr 
   */
  getOneArray (arr, data) {
    let result = []
    main(arr, result)
    return result

    function main (arr, result) {
      for (let i = 0; i < arr.length; i++) {

        let obj = {}
        obj.unitId = arr[i].unitId
        obj.unitStep = arr[i].unitStep
        obj.unitWidth = arr[i].unitWidth
        obj.unitHeight = arr[i].unitHeight
        obj.unitBasicStep = arr[i].unitBasicStep
        obj.unitElement = getSortByWight(arr[i].unitElement)
        obj.conditionNum = arr[i].conditionNum
        obj.contentNature = arr[i].contentNature
        result.push(obj)
        if (arr[i].conditionNum > 0) {
          sin(arr[i].selectObject, arr[i].conditionNum, result)
        }
      }
    }

    function sin (obj, num, result) {
      for (let i = 0; i < num; i++) {
        let tt = getSonBranchKey(i + 1)
        main(obj[tt], result)
      }
    }

    /**
     * 按权值 升序排序
     * @param {array} arrElement 接收每个步骤模块中包含的元素模块
     */
    function getSortByWight (arrElement) {
      return arrElement.sort((a, b) => { return a.weight - b.weight })
    }
  }

  /**
   * 这是一个添加模块的
   * 接收一个递归数组 并返回一个对象
   * @param  dragObj 拖拽对象
   * @param uId 准备操作的标记位置
   * @param arr 递归数组
   */
  getAddOneArray (dragObj, uId, selectFlag, arr) {
    let result = returnArray()
    result.newArray = arr
    // 判断是否是是第一个元素
    result = arr.length > 0 ? getAllArrayUl(dragObj, uId, selectFlag, result) : getUlNewArray(dragObj.eng, result)
    console.log('处理内容展示')
    console.log(result)
    return result
  }

  /**
   * 这是一个删除模块
   * 接收一个递归数组，返回一个对象
   * @param {number} weight 
   * @param {number} uId 
   * @param {array} arr 
   */
  getDeleteTarget (weight, uId, arr) {
    let result = returnArray()
    result.newArray = arr
    let consultArr = this._data
    deleteData(weight, uId, result, consultArr)
    console.log('删除数据成功')
    console.log(result)
    return result
  }

  /**
   * 对外暴露一个兼容版本处理，处理因describeObj结构的更改 
   * 对之前版本的不支持 兼容
   * @param {*} obj 
   */
  updateDescribeObj () {
    return {
      // 更改 状态输入
      updateStateInput: (obj) => stateInputFn(obj)
    }

    function stateInputFn (o) {
      if (!o.hasOwnProperty('state')) {
        o.state = []
        o.state.push(o.state_1)
        o.state.push(o.state_2)
      }
      console.log(o)
      return o
    }
  }

  /**
   * 转码模块 方便提交
   * @param arr 接收一个数组
   */
  turnSubmit (arrays) {
    let OneItemData = this.getStrategyData()
    let tt = {
      'dataArray': arrays
    }
    // 复制数组
    let result = JSON.parse(JSON.stringify(tt))
    main(result.dataArray)
    // 做排序
    console.log('排序后')
    console.log(result)
    return result
    function main (arr) {
      for (let i = 0; i < arr.length; i++) {
        delete arr[i].unitId
        delete arr[i].unitBasicStep
        delete arr[i].unitHeight
        delete arr[i].unitStep
        delete arr[i].unitElement
        delete arr[i].unitWidth
        // 数据备份拷贝
        var _testCopy = [].concat(JSON.parse(JSON.stringify(arr[i].contentNature)))
        arr[i].contentNatureXorY = siteOrder(_testCopy)
        arr[i].selectObjectData = []
        if (arr[i].conditionNum > 0) {
          arr[i].selectObjectData = selectObjectDele(arr[i].selectObject, arr[i].conditionNum)
          son(arr[i].selectObject, arr[i].conditionNum)
        }
      }
    }
    function son (obj, num) {
      for (let i = 0; i < num; i++) {
        let tts = getSonBranchKey(i + 1)
        main(obj[tts])
      }
    }

    /**
     * 添加眼镜所需的数据结构
     *  区分出x轴和y轴
     *  添加所在轴线的位置
     * @param {array} newArr 全部详情模块
     */
    function siteOrder (newArr) {
      let rules = [OneItemData.scan.eng, OneItemData.step.eng, OneItemData.select.eng, OneItemData.call.eng, OneItemData.finish.eng]
      let rulesY = [OneItemData.picture.eng, OneItemData.pdf.eng, OneItemData.video.eng, OneItemData.voice.eng, OneItemData.textInput.eng, OneItemData.video_record.eng, OneItemData.photo_record.eng, OneItemData.stateInput.eng, OneItemData.stateSelect.eng]
      let nameX = []
      let nameY = []

      newArr.forEach(item => {
        let flagNum = rules.indexOf(item.name)
        // eslint-disable-next-line no-unused-expressions
        flagNum > -1 ? nameX.push(rules[flagNum]) : null
      })

      newArr.forEach(item => {
        let flagNum = rulesY.indexOf(item.name)
        // eslint-disable-next-line no-unused-expressions
        flagNum > -1 ? nameY.push(rulesY[flagNum]) : null
      })

      for (let i = 0; i < newArr.length; i++) {
        newArr[i].XorY = rules.indexOf(newArr[i].name) > -1
        newArr[i].stepIndex = returnIndex(newArr[i].XorY, newArr[i].name, nameX, nameY)
        newArr[i].describeObj = jointData(newArr[i].describeObj, newArr[i].name)
      }
      return newArr
    }

    /**
     * 返回selectObject中统一
     * @param {*} obj selectObject
     * @param {*} num 角标数量
     */
    function selectObjectDele (obj, num) {
      console.log(obj)
      let result = []

      for (let i = 0; i < num; i++) {
        result.push({ dataArray: [] })
        let tts = getSonBranchKey(i + 1)
        result[i].dataArray = obj[tts]
      }
      return result
    }

    /**
     * 返回角标 方便确认位置
     * @param {boolean} flag 是否是x轴上 或者Y轴上
     * @param {string} name 每个模块中详情中的 name
     * @param {array} arrsX 每个模块中x轴 组成的数组
     * @param {array} arrsY 每个模块中y轴 组成的数组
     */
    function returnIndex (flag, name, arrsX, arrsY) {
      return flag ? arrsX.indexOf(name) : arrsY.indexOf(name)
    }

    /**
     * 每个详情模块 拼接成 |
     * @param {object} obj 每个详情模块
     * @param {string} name 
     * // 不足每次都需要自上而下执行 （需要更改）
     */
    function jointData (obj, name) {
      let str = ''
      let flag = '|'
      // let result = {}
      switch (name) {
        case OneItemData.scan.eng:
        case OneItemData.finish.eng:
          str = null
          break
        case OneItemData.step.eng:
          str = getStep(obj, flag)
          break
        case OneItemData.textInput.eng:
          str = obj.title + flag + obj.content
          break
        case OneItemData.pdf.eng:
          str = obj.url
          break
        case OneItemData.voice.eng:
          str = obj.text
          break
        case OneItemData.call.eng:
          str = getCall(obj, flag)
          break
        case OneItemData.picture.eng:
          str = getPicture(obj, flag)
          break
        case OneItemData.video.eng:
          str = obj.url + flag + obj.imageUrl
          break
        case OneItemData.photo_record.eng:
        case OneItemData.video_record.eng:
          str = obj.title
          break
        case OneItemData.stateInput.eng:
          str = getStateInput(obj, flag)
          break
        case OneItemData.stateSelect.eng:
          str = getStateSelect(obj, flag)
          break
        case OneItemData.select.eng:
          str = getSelect(obj, flag)
          break
        default:
          str = ''
      }
      return str
    }
    function getStep (o, flag) { // obj.title + flag + obj.content + flag + obj.site
      let result = null
      if (o.title !== '' || o.content !== '' || o.site !== '') {
        result = o.title + flag + o.content + flag + o.site
      }
      return result
    }
    /**
     * 返回call呼叫内容
     * @param {*} o 
     * @param {*} flag 
     */
    function getCall (o, flag) {
      let rr = o.expertName + flag + o.expertPhone
      return rr
    }
    /**
     * 返回图片的拼接
     * @param {*} o 
     * @param {*} flag 
     */
    function getPicture (o, flag) {
      let arr = o.imageArr
      if (arr !== undefined) {
        let rr = ''
        for (let i = 0; i < arr.length; i++) {
          (i === arr.length - 1) ? (rr += arr[i].url) : (rr += arr[i].url + flag)
        }
        return rr
      }
    }

    /**
     * 返回选择的的拼接
     * @param {*} o describeObj
     * @param {*} flag 
     */
    function getSelect (o, flag) {
      let arr = o.titleArr
      if (arr !== undefined) {
        let rr = o.title + flag
        for (let i = 0; i < arr.length; i++) {
          (i === arr.length - 1) ? (rr += arr[i].name) : (rr += arr[i].name + flag)
        }
        return rr
      }
    }

    function getStateInput (o, flag) {
      let arr = o.state
      if (arr !== undefined) {
        let newArr = arr.filter(str => str && str.trim()) //  去掉空字符串
        return o.title + flag + newArr.join(flag)
      }
    }

    function getStateSelect (o, flag) {
      let titleArr = []
      let result = null
      let stateArr = o.state
      if (o.title.length) {
        let flagText = o.title[0].isCJ ? 'cj' : 'nt'
        o.title.forEach(item => {
          titleArr.push(item.name)
          titleArr.push(item.pmid)
        })
        result = titleArr.concat(stateArr).join(flag)
        result = result + flag + flagText
      }
      return result
    }
  }
  /**
   * 解码模块 方便展示
   * @param {array} arrays 
   */
  decodeJson (arrays) {
    let consultArr = this._data
    let OneItemData = this.getStrategyData()
    main(arrays.dataArray)
    function main (arr) {
      for (let i = 0; i < arr.length; i++) {
        arr[i].unitId = tool.getRandomNum()
        if (i === 0) {
          arr[i].unitBasicStep = { 'left': unitFirstPosition.left, 'top': unitFirstPosition.top }
        } else {
          arr[i].unitBasicStep = { 'left': 0, 'top': 0 }
        }
        arr[i].unitHeight = 0
        arr[i].unitWidth = 0
        arr[i].unitStep = '0'
        arr[i].unitElement = getElemnt(arr[i].contentNature, consultArr)
        if (arr[i].conditionNum > 0) {
          son(arr[i].selectObject, arr[i].conditionNum)
        }
      }
    }
    function son (obj, num) {
      for (let i = 0; i < num; i++) {
        let tts = getSonBranchKey(i + 1)
        main(obj[tts])
      }
    }
    function getElemnt (newArr, oldArr) {
      let result = []
      for (let i = 0; i < newArr.length; i++) {
        let tt = oldArr.filter(item => item.eng === newArr[i].name)[0]
        if (tt !== undefined && newArr[i].name !== OneItemData.step.eng) {
          let obj = {
            'text': tt.text,
            'weight': tt.weight
          }
          result.push(obj)
        }
      }
      return result
    }
    return arrays
  }
}

/**
 * 定义返回数据格式
 * @returns {object}
 */
function returnArray () {
  return {
    newArray: [],
    error: {
      flag: false,
      errorText: ''
    },
    success: {
      flag: false,
      successText: ''
    }
  }
}

/**
 * 处理替换 添加其他子元素的操作
 * @param {object} dragObj 拖拽内容
 * @param {string} uId 操作uid
 * @param {string} selectFlag 选择的权值 -1 或者 4.1
 * @param {object} obj 这个对象是
 */
function getAllArrayUl (dragObj, uId, selectFlag, obj) {
  console.log('拖拽内容')
  console.log(dragObj)
  console.log('操作uid' + uId)
  console.log('这个对象是')
  console.log(obj)
  console.log('是否选中了  选择模块', selectFlag)

  obj.error = uId === '-1' ? tool.getErrorTip('请先选择你需要操作的步骤按钮') : ''
  if (uId !== '-1') {
    // 这里面有三件事，
    // 第一件事 是否需要在在步骤后面添加新步骤(或者是在选择器下面添加新分支)
    // 第二件事 是否是选择器
    // 第三件事 操作目的是添加或者替换
    if (WeightNum.IsStep(dragObj.weight)) { // 第一件事
      getArrayAddBasicStep(dragObj, uId, selectFlag, obj)
    } else if (WeightNum.IsSelect(dragObj.weight)) { // 是否是选择器
      getArrayAddSelect(dragObj, uId, obj)
    } else { // 添加或者替换
      getArrayAddOrReplace(dragObj, uId, obj)
    }
  }
  return obj
}

/**
 * 拖拽内容是步骤 想要在步骤后面添加新步骤
 * @param {object} dragObj 拖拽对象
 * @param {string} uId 唯一的uid
 * @param {string} selectFlag 是否在选择中添加步骤
 * @param {object} obj 所有对象
 */
// 处理添加基本步骤
function getArrayAddBasicStep (dragObj, uId, selectFlag, obj) {
  console.log('准备添加基本步骤了')
  let flagUID = '-1' // 初始化父集uid
  let flagSon = '-1' // 记录儿子值
  let parentObj = obj // 记录父亲对象
  let dragEng = dragObj.eng
  mainAdd(obj.newArray, flagUID, flagSon, parentObj)

  function mainAdd (arr, flagUID, flagSon, parentObj) {
    for (let i = 0; i < arr.length; i++) {
      if (arr[i].unitId === uId) {
        console.log('选择标志位' + selectFlag)
        selectFlag === '-1' ? addMin(i) : addSelect(i, arr)
        break
      } else if (arr[i].conditionNum > 0) {
        sonAdd(arr[i].selectObject, arr[i].conditionNum)
      }
    }

    function addMin (i) { // 添加主线步骤
      // 拆分并合并
      let sonArr = mergeArray(dragEng, i, arr)
      if (flagUID === '-1') {
        parentObj.newArray = sonArr
      } else {
        parentObj[flagSon] = sonArr
      }
    }
    // 合并数组
    function mergeArray (dragEng, flagI, arr) {
      let result
      let arr1 = []
      let arr2 = []
      for (let i = 0; i <= flagI; i++) {
        arr1.push(arr[i])
      }

      arr1.push(getUlNewJson(dragEng))

      for (let j = (flagI + 1); j < arr.length; j++) {
        arr2.push(arr[j])
      }
      console.log(arr2)
      result = [...arr1, ...arr2]
      return result
    }
  }

  function addSelect (i, arr) {
    let tt = getSonBranchKey((arr[i].conditionNum + 1))
    arr[i].contentNature = addBranchName(arr[i].contentNature, tt)
    arr[i].selectObject[tt] = []
    arr[i].selectObject[tt].push(getUlNewJson(dragObj.eng))
  }

  function sonAdd (obj, num) {
    for (let i = 0; i < num; i++) {
      let tt = getSonBranchKey(i + 1)
      mainAdd(obj[tt], '1', tt, obj)
    }
  }

  /**
   * 每添加一个分支后 给contentNature中的选择模块添加名字
   * @param {Array} natureArr contentNature 数组
   * @param {String} branchName 分支名字
   */
  function addBranchName (natureArr, branchName) {
    natureArr.filter(item => item.name === 'select')[0].describeObj.titleArr.push({ 'name': '', 'branch': branchName })
    return natureArr
  }
}

/**
 * 处理添加选择器 拖拽内容是选择器
 * @param {object} dragObj 拖拽对象
 * @param {sting} uId 唯一uid
 * @param {object} obj 所有对象
 */
function getArrayAddSelect (dragObj, uId, obj) {
  mainFindUId(obj.newArray)

  function mainFindUId (arr) {
    for (let i = 0; i < arr.length; i++) {
      if (arr[i].unitId === uId) {
        let isHaveFlag = isHave(arr[i].unitElement, dragObj)
        console.log('添加或者替换是检测结果为：' + isHaveFlag)
        if (isHaveFlag !== -1) {
          arr[i].unitElement.push({ text: dragObj.text, weight: dragObj.weight }) // 插入标准位
          arr[i].conditionNum = 1
          arr[i].selectObject['condition_1'] = []
          arr[i].selectObject['condition_1'].push(getUlNewJson('step'))
          arr[i].contentNature.push(getNatureData(dragObj.eng))
        } else {
          obj.error = tool.getErrorTip('已经存在了不需要再添加了')
        }
        break
      } else if (arr[i].conditionNum > 0) {
        sonFindUId(arr[i].selectObject, arr[i].conditionNum)
      }
    }
  }

  function sonFindUId (obj, num) {
    for (let i = 0; i < num; i++) {
      let tt = getSonBranchKey(i + 1)
      mainFindUId(obj[tt])
    }
  }
}

/**
 * 处理对拽内容除步骤和选择以外的元素 添加或者替换
 * @param {object} dragObj 拖拽对象
 * @param {string} uId uid
 * @param {object} obj 所有对象
 */
function getArrayAddOrReplace (dragObj, uId, obj) {
  mainFindUId(obj.newArray)

  function mainFindUId (arr) {
    for (let i = 0; i < arr.length; i++) {
      if (arr[i].unitId === uId) {
        let isHaveFlag = isHave(arr[i].unitElement, dragObj)
        console.log('添加或者替换是检测结果为：' + isHaveFlag)
        let isHaves = parseInt(isHaveFlag)
        if (isHaves === -2) { // 可直接插入
          arr[i].unitElement.push({ text: dragObj.text, weight: dragObj.weight }) // 插入标准位
          arr[i].contentNature.push(getNatureData(dragObj.eng))
        } else if (isHaves === -1) {
          obj.error = tool.getErrorTip('已经存在了不需要再添加了')
        } else { // 替换元素
          // 替换属性
          let replaceEng = objectTask.getEngByChinese(arr[i].unitElement[isHaves].text)
          console.log(replaceEng)
          let deleteNum = arr[i].contentNature.findIndex(item => item.name === replaceEng)
          console.log('准备删除的角标' + deleteNum)
          arr[i].contentNature.splice(deleteNum, 1)
          arr[i].contentNature.push(getNatureData(dragObj.eng))
          arr[i].unitElement[isHaves].text = dragObj.text // 替换元素
        }
        break
      } else if (arr[i].conditionNum > 0) {
        sonFindUId(arr[i].selectObject, arr[i].conditionNum)
      }
    }
  }

  function sonFindUId (obj, num) {
    for (let i = 0; i < num; i++) {
      let tt = getSonBranchKey(i + 1)
      mainFindUId(obj[tt])
    }
  }
}
/**
 * 返回
 * -2 ：可直接添加 
 * -1 ：不需要添加 
 * 角标值：替换文字
 * @param {array} array 存储的element记录
 * @param {object} dragObj 拖拽内容
 */
function isHave (array, dragObj) {
  let result = -2
  if (array.length === 0) { // 可直接添加
    result = -2
  } else {
    for (let i = 0; i < array.length; i++) {
      if (array[i].weight === dragObj.weight && array[i].text === dragObj.text) {
        result = -1
        break
      } else if (array[i].weight === dragObj.weight) {
        result = i
        break
      } else {
        result = -2
      }
    }
  }
  return result
}

/**
 * 当添加第一个时
 * @param {string} dragEng 拖拽的英文标志
 * @param {object} obj 存储的全部数据
 */
function getUlNewArray (dragEng, obj) {
  let OneItemData = objectTask.getStrategyData()
  if (dragEng !== OneItemData.step.eng) {
    obj.error = tool.getErrorTip('请先添加步骤')
  } else {
    obj.newArray.push(getUlNewJson(dragEng))
    obj.newArray[0].unitBasicStep.top = unitFirstPosition.top
    obj.newArray[0].unitBasicStep.left = unitFirstPosition.left
  }
  return obj
}

/**
 * 创建新元素
 * @param {string} dragEng 拖拽的英文标志
 */
function getUlNewJson (dragEng) {
  let result = getInitBaseUlData()
  result.contentNature = []
  console.log('拖拽内容是：' + dragEng)
  console.log(getNatureData(dragEng))
  result.contentNature.push(getNatureData(dragEng))
  return result
}
/**
 * 返回每个操作对象的具体初始化参数
 * @param {string} dragEng 拖拽的英文标志
 */
function getNatureData (dragEng) {
  return getInitNatureData().filter(item => item.name === dragEng)[0]
}

/**
 * 处理删除操作
 * @param {number} wei 权值 
 * @param {string} uId 每个步骤模块唯一标识
 * @param {object} obj 整个模块对象
 * @param {array} consultArr this._data数据 每个模块的数据记录
 */
function deleteData (wei, uId, obj, consultArr) {
  // 分3步骤
  main(obj.newArray)
  function main (arr) {
    for (let i = 0; i < arr.length; i++) {
      if (arr[i].unitId === uId) {
        if (WeightNum.IsStep(wei)) { // 第一 删除权值是 步骤
          deleteBasicStep(arr, i)
        } else if (WeightNum.IsSelect(wei)) { // 第二 删除权值是 选择
          console.log('开始删除选择了 通知')
          arr[i].selectObject = {}
          arr[i].contentNature = deleteContentNatureData(arr[i].contentNature, arr[i].unitElement, wei, consultArr)
          arr[i].unitElement = deleteOtherData(arr[i].unitElement)
        } else { // 第三 删除权值是 其他
          arr[i].contentNature = deleteContentNatureData(arr[i].contentNature, arr[i].unitElement, wei, consultArr)
          arr[i].unitElement = deleteOtherData(arr[i].unitElement)
        }
        break
      } else if (arr[i].conditionNum > 0) {
        son(arr[i].selectObject, arr[i].conditionNum)
      }
    }
  }

  function son (obj, num) {
    for (let i = 0; i < num; i++) {
      let tt = getSonBranchKey(i + 1)
      main(obj[tt])
    }
  }

  // 处理删除其他元素
  function deleteOtherData (deleteArr) {
    let result = deleteArr.filter(item => item.weight !== wei)
    obj.success = tool.getSuccessTip('已删除元素')
    return result
  }

  // 处理删除基本步骤
  function deleteBasicStep (arr, i) {
    arr.splice(i, 1)
  }

  /**
   * 删除子模块
   * @param {*} data contentNature 详情模块
   * @param {*} ele unitElement 元素模块
   * @param {*} ww 权值
   * @param {*} conArr 原数据
   */
  function deleteContentNatureData (data, ele, ww, conArr) {
    let chi = ele.filter(tt => tt.weight === ww)[0].text
    let eng = conArr.filter(ss => ss.text === chi)[0].eng
    let result = data.filter(ww => ww.name !== eng)
    return result
  }
}

/**
 * 返回基本的数据结构
 * @returns {object}
 */
function getInitBaseUlData () {
  return {
    'unitId': tool.getRandomNum(),
    'unitStep': '0',
    'unitWidth': 0,
    'unitHeight': 0,
    'unitBasicStep': { 'left': 0, 'top': 0 },
    'unitElement': [],
    'conditionNum': 0,
    'selectObject': {},
    'contentNature': []
  }
}

/**
 * 比较某个数组对象中的 key 所对应的值是否等于 value值
 * @param {*} arr 数组对象
 * @param {*} key key值
 * @param {*} value 比较值
 */
function arrIsHasValue (arr, key, value) {
  return arr.filter(item => item[key] === value).length > 0
}

/**
 * 返回数组对象中不含有value值的 数组对象
 * @param {*} arr 数组对象
 * @param {*} key key值
 * @param {*} value 不含有的值
 */
function getArrNoHasValue (arr, key, value) {
  return arr.filter(item => item[key] !== value)
}

/**
 * 返回选择 的子分支 key值 selectObject的key值
 * @param {*} num 
 */
function getSonBranchKey (num) {
  return 'condition_' + num
}
// 子属性内容
/**
 * 详情模块
 * @returns {array}
 */
function getInitNatureData () {
  return [
    {
      'name': 'step',
      'status': "0",//步骤状态
      'describeObj': {
        'title': '',
        'content': '',
        'site': ''
      }
    },
    {
      'name': 'scan',
      'describeObj': {}
    },
    {
      'name': 'picture',
      'describeObj': {
        'imageArr': []
      }
    },
    {
      'name': 'pdf',
      'describeObj': {
        'pdfUrls': [],
      }
    },
    {
      'name': 'voice',
      'describeObj': {
        'text': ''
      }
    },
    {
      'name': 'video',
      'describeObj': {
        'videoUrls': []

      }
    },

    {
      'name': 'video_record',
      'describeObj': {
        'title': ''
      }
    },
    {
      'name': 'photo_record',
      'describeObj': {
        'title': ''
      }
    },
    {
      'name': 'stateInput',
      'describeObj': {
        'title': '主题1',
        'state': ['正常', '异常']
      }
    },
    {
      'name': 'stateSelect',
      'describeObj': {
        'title': [
          // {
          //   name: '',
          //   pmid:''
          // }
        ],
        'state': ['正常', '异常']
      }
    },
    {
      'name': 'call',
      'describeObj': {
        'title': '测试',
        'expertName': '',
        'expertPhone': '',
        'expert': [
          { 'name': '', 'phone': '' }
        ]
      }
    },
    {
      'name': 'finish',
      'describeObj': {
        'title': ''
      }
    },
    {
      'name': 'select',
      'describeObj': {
        'title': '主题',
        'titleArr': [
          {
            'name': '',
            'branch': 'condition_1'
          }
        ]
      }
    }
  ]
}
const objectTask = new StandardData()
export default objectTask
